package com.cdtye.shuoh.controller.play;

import com.alibaba.fastjson.JSONObject;
import com.cdtye.shuoh.config.gb28181.bean.StreamInfo;
import com.cdtye.shuoh.config.gb28181.storage.IRedisCatchStorage;
import com.cdtye.shuoh.config.gb28181.transmit.callback.DeferredResultHolder;
import com.cdtye.shuoh.config.gb28181.transmit.callback.RequestMessage;
import com.cdtye.shuoh.config.gb28181.transmit.cmd.impl.SIPCommander;
import com.cdtye.shuoh.domain.device.entity.Device;
import com.cdtye.shuoh.service.device.DeviceService;
import com.cdtye.shuoh.service.play.PlayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.sip.message.Response;
import java.util.UUID;

/**
 * 视频回放
 * @author ZhongWang Wang
 * @date 2022-12-21
 */
@RestController
@RequestMapping(value = "/playback")
@ConditionalOnProperty(value = "sip.enabled", havingValue = "true")
public class PlayBackController {
    private final static Logger logger = LoggerFactory.getLogger(PlayBackController.class);

    @Autowired
    private SIPCommander cmder;

    @Autowired
    private IRedisCatchStorage redisCatchStorage;

    @Autowired
    private DeferredResultHolder resultHolder;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private PlayService playService;

    /**
     * 开始视频回放
     * @param deviceIdentification
     * @param channelId
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping(value="/start")
    public DeferredResult<ResponseEntity<String>> play(String deviceIdentification, String channelId, String startTime,
                                                       String endTime) {

        if (logger.isDebugEnabled()) {
            logger.debug(String.format("设备回放 API调用，deviceIdentification：%s ，channelId：%s", deviceIdentification, channelId));
        }
        UUID uuid = UUID.randomUUID();
        DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
        // 超时处理
        result.onTimeout(()->{
            logger.warn(String.format("设备回放超时，deviceIdentification：%s ，channelId：%s", deviceIdentification, channelId));
            RequestMessage msg = new RequestMessage();
            msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
            msg.setData("Timeout");
            resultHolder.invokeResult(msg);
        });
        Device device = deviceService.findOneByDeviceIdentification(deviceIdentification);
        StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceIdentification, channelId);
        if (streamInfo != null) {
            // 停止之前的回放
            cmder.streamByeCmd(streamInfo.getStreamId());
        }
        resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
        cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> {
            logger.info("收到订阅消息： " + response.toJSONString());
            playService.onPublishHandlerForPlayBack(response, deviceIdentification, channelId, uuid.toString());
        }, event -> {
            Response response = event.getResponse();
            RequestMessage msg = new RequestMessage();
            msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
            msg.setData(String.format("回放失败， 错误码： %s, %s", response.getStatusCode(), response.getReasonPhrase()));
            resultHolder.invokeResult(msg);
        });

        return result;
    }

    @GetMapping("/stop")
    public ResponseEntity<String> playStop(String ssrc) {

        cmder.streamByeCmd(ssrc);

        if (logger.isDebugEnabled()) {
            logger.debug(String.format("设备录像回放停止 API调用，ssrc：%s", ssrc));
        }

        if (ssrc != null) {
            JSONObject json = new JSONObject();
            json.put("ssrc", ssrc);
            return new ResponseEntity<String>(json.toString(), HttpStatus.OK);
        } else {
            logger.warn("设备录像回放停止API调用失败！");
            return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}
